﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel.Composition;

using NuMetaheuristics.Genotypes;
using NuMetaheuristics.Operators.Vector;
using NuMetaheuristics.Operators.Value;

namespace NuMetaheuristics.Contexts.Vector.Double
{
    [DataContract(Namespace = "http://numetaheuristics.codeplex.com/schemas")]
    [Export(typeof(IContext<DoubleVectorGenotype>))]
    public class Griewank : DoubleVectorContext
    {
        public Griewank()
            : base()
        {
        }

        public Griewank(int length)
            : base(length, -600, 600)
        {
        }

        override public void Evaluate(ref DoubleVectorGenotype genome)
        {
            double total = 1.0;
            double sum = 0.0;
            double product = 1.0;

            for (uint i = 0; i < genome.Vector.Length; i++ )
            {
                double x = genome.Vector[i];
                double a = x / Math.Sqrt(i);

                sum += (x * x);
                product *= Math.Cos(a);
            }

            total += (sum / 4000.0);
            total += product;

            genome.Fitness = new FitnessSmallerIsBetter(total);
        }
    }
}
